/**
 * @author bbroome
 */

$.extend(String, {
  interpret: function(value) {
    return value == null ? '' : String(value);
  }
});

$.extend(String.prototype, {
  tokenize: function(seperator) {
    var string = this.strip();
    return string ? string.split($._R.WP) : [];
  },

  strip: function() {
    return this.replace($._R.WF, '').replace($._R.WB, '');
  },

  stripTags: function() {
    return this.replace($._R.T, '');
  },

  stripScripts: function() {
    return this.replace($._R.AS, '');
  },

  extractScripts: function() {
    return (this.match($._R.AS) || []).map(function(scriptTag) {
      return (scriptTag.match($._R.OS) || ['', ''])[1];
    });
  },

  evalScripts: function() {
    return this.extractScripts().map(function(script) { return eval(script) });
  },

  escapeHTML: ($.WebKit || $.IE ? function() {
    return this.replace($._R.Amp,'&amp;').replace(
      $._R.LT,'&lt;').replace($._R.GT,'&gt;');
  } : function() {
    $._escaper.text.data = this;
    return $._escaper.div.innerHTML;
  }),

  unescapeHTML: ($.WebKit || $.IE ? function() {
    return this.replace($._R.AmpE,'&').replace(
      $._R._L,'<').replace($._R._G,'>');
  } : function() {
    var div = new Element('div').insert(this.stripTags());
    return div.childNodes[0] ? (div.childNodes.length > 1 ?
      $.A(div.childNodes).inject('', 
          function(memo, node) { return memo + node.nodeValue }) :
      div.childNodes[0].nodeValue) : '';
  }),

  toQueryParams: function(separator) {
    var match = this.strip().match($._R.QP);
    if (!match) return {};

    return match[1].split(separator || '&').inject({}, function(hash, pair) {
      if ((pair = pair.split('='))[0]) {
        var key = decodeURIComponent(pair.shift());
        var value = pair.length > 1 ? pair.join('=') : pair[0];
        if (value != undefined) value = decodeURIComponent(value);

        if (key in hash) {
          if (!$.isArray(hash[key])) hash[key] = [hash[key]];
          hash[key].push(value);
        }
        else hash[key] = value;
      }
      return hash;
    });
  },

  toArray: function() {
    return this.split('');
  },

  next: function() {
    return this.slice(0, this.length - 1) +
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  },

  times: function(count) {
    return count < 1 ? '' : new Array(count + 1).join(this);
  },

  camelize: function() {
    var parts = this.split('-'), len = parts.length;
    if (len == 1) return parts[0];

    var camelized = this.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
  },

  capitalize: function() {
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  },

  underscore: function() {
    return this.gsub($._R.DC, '/').gsub($._R.C,'#{1}_#{2}').gsub(
      $._R.EC,'#{1}_#{2}').gsub($._R.D,'_').toLowerCase();
  },
  
  dasherize: function() {
    return this.gsub($._R.U,'-');
  },

  inspect: function(useDoubleQuotes) {
    var escapedString = this.gsub($._R.UC, function(match) {
      var character = String.specialChar[match[0]];
      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
    });
    return useDoubleQuotes ? ('"' + escapedString.replace($._R.DQ, '\\"') + '"') :
           ("'" + escapedString.replace($._R.SQ, '\\\'') + "'");
  },

  toJSON: function() {
    return this.inspect(true);
  },
  
  isJSON: function() {
    return ($._R.JS).test(
      this.replace($._R.P, '@').replace($._R.SC, ''));
  },

  evalJSON: function(sanitize) {
    try {
      if (!sanitize || this.isJSON()) return eval('(' + this + ')');
    } catch (e) {}
    throw new SyntaxError('Not JSON: ' + this.inspect());
  },

  include: function(pattern) {
    return this.indexOf(pattern) >= 0;
  },

  startsWith: function(pattern) {
    return this.indexOf(pattern) === 0;
  },

  endsWith: function(pattern) {
    var d = this.length - pattern.length;
    return d >= 0 && this.lastIndexOf(pattern) === d;
  },

  empty: function() {
    return this == '';
  },

  blank: function() {
    return $._R.B.test(this);
  },

  interpolate: function(object, pattern) {
    return new $.Template(this, pattern).evaluate(object);
  }
});

if ($.WebKit || $.IE) $.extend(String.prototype, {
  escapeHTML: function() {
    return this.replace($._R.Amp,'&amp;').replace(
      $._R.LT,'&lt;').replace($._R.GT,'&gt;');
  },
  unescapeHTML: function() {
    return this.replace($._R.AmpE,'&').replace(
      $._R._L,'<').replace($._R._G,'>');
  }
});
